package com.example.demofdfs.example.map;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ArrayMap<K, V> implements Map<K, V> {

	List<Entry<K, V>> entrys;

	private class Node<K, V> implements Entry<K, V> {

		K k;
		V v;

		public Node(K k, V v) {
			super();
			this.k = k;
			this.v = v;
		}

		@Override
		public K getKey() {
			return k;
		}

		@Override
		public V getValue() {
			return v;
		}

		@Override
		public V setValue(V value) {
			V old = v;
			this.v = value;
			return old;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((k == null) ? 0 : k.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			@SuppressWarnings("unchecked")
			Node<K, V> other = (Node) obj;
			if (k == null) {
				if (other.k != null)
					return false;
			} else if (!k.equals(other.k))
				return false;
			return true;
		}

		@Override
		public String toString() {
			return k + "=" + v;
		}

	}

	public ArrayMap() {
		this.entrys = new ArrayList<>();
	}

	public ArrayMap(int initcapacity) {
		this.entrys = new ArrayList<>(initcapacity);
	}

	@Override
	public int size() {
		return entrys.size();
	}

	@Override
	public boolean isEmpty() {
		return entrys.size() == 0;
	}

	@Override
	public boolean containsKey(Object key) {
		return getEntry(key) != null;
	}

	private Entry<K, V> getEntry(Object key) {
		if (key == null) {
			return null;
		}

		Iterator<Entry<K, V>> it = entrys.iterator();
		Entry<K, V> n;
		while (true) {
			if (!it.hasNext()) {
				return null;
			}
			if (key.hashCode() == (n = it.next()).getKey().hashCode()) {
				return n;
			}
		}
	}

	@Override
	public boolean containsValue(Object value) {
		return false;
	}

	@Override
	public V get(Object key) {
		Entry<K, V> n;
		return (n = getEntry(key)) == null ? null : n.getValue();
	}

	@Override
	public V put(K key, V value) {
		Entry<K, V> n, newNode = new Node<>(key, value);
		int index;
		if ((index = entrys.indexOf(newNode)) != -1) {
			n = entrys.get(index);
			entrys.set(index, newNode);
			return n.getValue();
		} else {
			entrys.add(newNode);
		}
		return null;
	}

	@Override
	public V remove(Object key) {
		Entry<K, V> n = getEntry(key);
		if (n != null) {
			entrys.remove(n);
			return n.getValue();
		}
		return null;
	}

	@Override
	public void putAll(Map<? extends K, ? extends V> m) {
		// TODO Auto-generated method stub

	}

	@Override
	public void clear() {
		entrys.clear();
	}

	@Override
	public Set<K> keySet() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Collection<V> values() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Set<Entry<K, V>> entrySet() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String toString() {
		return entrys.toString();
	}

	public static <K, V> Map<K, V> syncMap(Map<K, V> map) {
		return new SyncMap<K, V>(map);
	}

	private static class SyncMap<K, V> implements Map<K, V> {
		Map<K, V> map;

		public SyncMap(Map<K, V> map) {
			super();
			this.map = map;
		}

		@Override
		public int size() {
			synchronized (map) {
				return map.size();
			}
		}

		@Override
		public boolean isEmpty() {
			synchronized (map) {
				return map.isEmpty();
			}
		}

		@Override
		public boolean containsKey(Object key) {
			// TODO Auto-generated method stub
			return false;
		}

		@Override
		public boolean containsValue(Object value) {
			// TODO Auto-generated method stub
			return false;
		}

		@Override
		public V get(Object key) {
			synchronized (map) {
				return map.get(key);
			}
		}

		@Override
		public V put(K key, V value) {
			synchronized (map) {
				return map.put(key, value);
			}
		}

		@Override
		public V remove(Object key) {
			synchronized (map) {
				return map.remove(key);
			}
		}

		@Override
		public void putAll(Map<? extends K, ? extends V> m) {
			// TODO Auto-generated method stub

		}

		@Override
		public void clear() {
			// TODO Auto-generated method stub

		}

		@Override
		public Set<K> keySet() {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public Collection<V> values() {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public Set<Entry<K, V>> entrySet() {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public String toString() {
			synchronized (map) {
				return map.toString();
			}
		}

	}

}
